home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
TPUG - Toronto PET Users Group
/
TPUG Users Group CD
/
TPUG Users Group CD.iso
/
COMAL
/
T-COMAL Today
/
(k)ta.d64
/
musicroutine.src
< prev
next >
Wrap
Text File
|
2007-02-28
|
8KB
|
286 lines
;********************************
;* *
;* INTERRUPT DRIVEN *
;* *
;* SOUND INTERPRETER *
;* *
;********************************
;
;--------------------------------
;USES 2 ZERO PAGE LOCATIONS
;PUT ADDRESS OF DATA IN LO/HI
;FASHION AT THIS ADDRESS
;
SOUND = $F9 ;THESE ARE RS232
; ;POINTERS AND
; ;SHOULDN'T
; ;INTERFERE WITH
; ;COMAL.
;
;--------------------------------
;
IRQVC = $10E5
VOLUME = $D418
SID = $D400
*= $CDC0 ;ROUTINE USES
;RS232 BUFFER
;AND SPRITE
;NUMBER 55
;
BEGIN LDA #00
STA STACKP
INIT SEI ;SET UP TO PLAY MUSIC AT EVERY INTERRUPT
LDA #$FF ;SET TIMER
STA TIMER
LDA IRQVC ;EVERY 1/60
STA IRQSV ;GOTO LABEL
LDA IRQVC+1 ;RUN.
STA IRQSV+1
LDA #<RUN
STA IRQVC
LDA #>RUN
STA IRQVC+1
CLI
LDA #15
STA VOLUME
RTS
;
ENDSNG SEI ;STOP PLAYING MUSIC - WITHDRAW SEQUENCE
LDA IRQSV
STA IRQVC
LDA IRQSV+1
STA IRQVC+1
CLI
LDA #0
STA VOLUME
RTS
;
;
RUN STA ASAVE ;SAVE REG'S
STY YSAVE
STX XSAVE
LDY #$00 ;LOAD Y INDEX WITH ZERO OFFSET
CLD
INC TIMER ;INCREMENT TIMER
LDA (SOUND),Y
CMP TIMER ;COMPARE WITH NEXT PLAYING TIME
BEQ ISTIM
JMP JMPIRQ ;NOT TIME TO CHANGE ANYTHING
;
ISTIM JSR INCSND ;IT'S TIME SO GO TO NEXT INSTRUCTION
PLYNOT LDA (SOUND),Y ;GET NEXT BYTE
BMI SPCMD ;IF BIT #7 IS ON THEN IT IS A COMMAND BYTE
JSR INCSND ;ELSE IT IS A REGISTER NUMBER SO POINT TO NEXT
TRNREG TAX
LDA (SOUND),Y ;LOAD BYTE TO GO TO SID CHIP
STA SID,X ;STORE BYTE IN SID CHIP
STA SIDREG,X ;AND IN MEMORY COPY (FOR READING PURPOSES)
JSR INCSND ;POINT TO NEXT BYTE
JMP PLYNOT ;JUMP BACK FOR NEXT COMMAND
SPCMD JSR INCSND ;THIS IS A COMMAND SO POINT TO NEXT BYTE
CMP #$F0
BEQ NTV1ON ;PLAY NOTE ON VOICE ONE
CMP #$F1 ;VOICE 2
BEQ NTV2ON
CMP #$F2 ;VOICE 3
BEQ NTV3ON
CMP #$F3 ;TURN VOICE 1 OFF (FINISHED ATTACK/DECAY/SUSTAIN)
BEQ NTV1OF
CMP #$F4 ;VOICE 2
BEQ NTV2OF
CMP #$F5 ;VOICE 3
BEQ NTV3OF
JMP NXTCMD ;NEXT CMD
;
NTV1ON JSR DEFNOT ;DEFINE NOTE
LDX #$00 ;FOR V1
JMP STRNOT ;STORE SAME
NTV2ON JSR DEFNOT
LDX #$07 ;FOR V2
JMP STRNOT
NTV3ON JSR DEFNOT
LDX #$0E ;FOR V3
JMP STRNOT
;
NTV1OF LDX #$04 ;VOICE 1 OFF
BNE NOTOFF
NTV2OF LDX #$0B ;VOICE 2 OFF
BNE NOTOFF
NTV3OF LDX #$12 ;V3 OFF
NOTOFF LDA SIDREG,X ;LOAD MEMORY COPY
AND #$FE ;TURN OFF GATE
STA SIDREG,X ;STORE IN MEMORY COPY
STA SID,X ;AND SID CHIP
JMP PLYNOT ;JUMP BACK FOR MORE
;
DEFNOT LDA (SOUND),Y ;LOAD NOTE
JSR INCSND
PHA ;SAVE NOTE
AND #$0F ;MASK FOR NOTE ONLY (BLOCK OUT OCTAVE)
ASL A ;MULTIPLY BY 2 TO PICK UP FREQ IN TABLE (2 BYTES)
TAX
LDA NOTE,X ;PICK UP LOW PART OF FREQ
STA ACCUML
INX
LDA NOTE,X ;PICK UP HI PART OF FREQ
STA ACCUMH
PLA ;PULL BACK NOTE
AND #$70 ;MASK FOR OCTAVE (0-7) IN UPPER FOUR BITS
LDX #$04
MKOCTV LSR A ;MOVE TO LOWER FOUR BITS
DEX
BNE MKOCTV
EOR #$07 ;FLIP TO FIGURE NUMBER OF TIMES TO SHIFT FREQ
TAX
INX ;LEAVE IN-MAKES NEXT LOOP EASIER
SFTFEQ DEX ;DIVIDE FREQ OF NOTE IN HALF FOR EVERY OCTAVE
BEQ FNSHFQ ;UNDER 7
LSR ACCUMH
ROR ACCUML
CLC
BCC SFTFEQ
FNSHFQ RTS ;PROPER FREQ IS READY - SO RETURN
;
STRNOT LDA ACCUML ;PUT FREQ
STA SID,X ;IN SID
STA SIDREG,X ;AND IN
INX ;MEMORY
LDA ACCUMH ;REG'S.
STA SID,X
STA SIDREG,X
INX
INX
INX
LDA SIDREG,X ;SWITCH ON
ORA #$01 ;GATE -
STA SID,X ;START NOTE
STA SIDREG,X
JMP PLYNOT ;BACK FOR MORE
;
NXTCMD CMP #$F7 ;IN-LINE MACHINE CODE ROUTINE
BNE NOTASM
JMP (SOUND)
NOTASM CMP #$FB ;ABSOLUTE JUMP
BEQ JMPDAT
CMP #$FC ;RETURN FROM SUBROUTINE
BEQ RTSMSR
CMP #$FD ;ABSOLUTE JSR
BEQ JSRMSR
CMP #$FE ;END OF CHANGES - NEXT BYTE IS TIMER BYTE
BEQ LSTCNG
CMP #$FF ;END SONG
BEQ FINISH
CMP #$FA ;ZERO SID
BEQ TRNOFF
CMP #$F9 ;RELATIVE JSR
BEQ BSRMSR
CMP #$F8 ;RELATIVE JUMP
BEQ BRAMSR
JMP FINISH ;NOT A KNOW COMMAND SO END SONG
;
JSRMSR JSR STKPOS ;SAVE RETURN ADDRESS
JMPDAT LDA (SOUND),Y ;JUMP TO NEXT INSTRUCTION
TAX
INY
LDA (SOUND),Y
STA SOUND
STX SOUND+1
JMP PLYNOT ;NEXT COMMAND
;
RTSMSR DEC STACKP ;PULL DOWN STACK POINTER
DEC STACKP
LDX STACKP
LDA STACK,X ;PUT STACK CONTENTS IN SOUND POINTER
STA SOUND
INX
LDA STACK,X
STA SOUND+1
JMP PLYNOT
;
LSTCNG LDA #$00 ;ZERO TIMER
STA TIMER
JMP JMPIRQ
;
FINISH LDA IRQSV ;WITHDRAW FROM INTERRUPT STRUCTURE
STA IRQVC
LDA IRQSV+1
STA IRQVC+1
JMP JMPIRQ
;
TRNOFF LDX #$18 ;ZERO SID CHIP
LDA #$00
LPOFF STA SID,X
STA SIDREG,X
DEX
BPL LPOFF
JMP PLYNOT
;
BSRMSR JSR STKPOS ;RELATIVE
BRAMSR LDY #$01 ;BRANCHING
LDA (SOUND),Y ;JUST LIKE
CLC ;6502
ADC SOUND ;(SAME
DEY ; FORMAT)
TAX
LDA (SOUND),Y
ADC SOUND+1
STA SOUND+1
STX SOUND
JMP PLYNOT
;
MUSIC PLA ;JSR HERE
STA SOUND ;AFTER MACHINE LANGUAGE ROUTINE
PLA
STA SOUND+1
JMP PLYNOT
;
JMPIRQ LDA ASAVE ;RESTORE
LDX XSAVE ;REG'S AND
LDY YSAVE ;CONTINUE
JMP (IRQSV) ;REGULAR IRQ
;
INCSND INC SOUND ;INCREMENT
BNE RTN ;POINTER
INC SOUND+1
RTN RTS
;
STKPOS LDX STACKP ;STACK RETURN ADDRESS OF NEXT COMMAND
LDA SOUND
CLC
ADC #$02
STA STACK,X
INX
LDA SOUND+1
ADC #$00
STA STACK,X
INC STACKP
INC STACKP
RTS
;
XSAVE .BYTE 0
YSAVE .BYTE 0
ASAVE .BYTE 0
IRQSV .BYTE 0,0
TIMER .BYTE 0
ACCUML .BYTE 0
ACCUMH .BYTE 0
NOTE .WORD 34334 ;FREQUENCY
.WORD 36376 ;TABLE TAKEN
.WORD 38539 ;FROM THE
.WORD 40830 ;COMMODORE 64
.WORD 43258 ;PROGRAMERS
.WORD 45830 ;REFERENCE
.WORD 48556 ;GUIDE.
.WORD 51443
.WORD 54502
.WORD 57743
.WORD 61176
.WORD 64814
STACKP .BYTE 0
SIDREG .BYTE 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
;
STACK .BYTE 0,0,0,0,0,0,0,0,0,0
.BYTE 0,0,0,0,0,0,0,0,0,0
;SPACE FOR 10 NESTED SUBROUTINE CALLS
.END